﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Core.Models;

namespace Core.Controllers
{
    [Permission("Can Administer BU, Can Create/Delete Domain, Can Modify Domain")]
    public class BusinessUnitController : Controller
    {
        //
        // GET: /BusinessUnit/

        public ActionResult Index()
        {            
            CoreEntities core = new CoreEntities();
            Guid domainid = (Guid)Session["DomainId"];
            Domain domain = core.Domains.First(m => m.DomainId == domainid);
            if (domain.IsMultiBUYN == "N")
            {
                List<BusinessUnit> BUs = core.BusinessUnits.Where(bu => (bu.IsDroppedYN == "N" && bu.DomainId == domainid)).ToList();
                if (BUs.Count < 1)
                {
                    return RedirectToAction("Create");
                }
                else
                {
                    return RedirectToAction("Details", new { id = BUs[0].BusinessUnitId});
                }
            }
            return View();
        }

        //
        // POST: /BusinessUnit/BUList/

        [HttpPost]
        public JsonResult BUList(FormCollection collection)
        {
            CoreEntities core = new CoreEntities();
            Guid DomainId = new Guid(collection.GetValues("DomainId")[0].ToString());
            int SkipRecs = int.Parse(collection.GetValues("iDisplayStart")[0].ToString());
            int TakeCount = int.Parse(collection.GetValues("iDisplayLength")[0].ToString());
            string strSearch = collection.GetValues("sSearch")[0].ToString();
            DataTableResponse r = new DataTableResponse();
            // Needs update when paging & sorting is implemented
            List<BusinessUnit> list = core.BusinessUnits.Where(m => (m.DomainId == DomainId && m.BusinessUnitName.Contains(strSearch) && m.IsDroppedYN == "N")).OrderBy(m => m.BusinessUnitName).Skip(SkipRecs).Take(TakeCount).ToList();
            r.sEcho = collection.GetValues("sEcho")[0].ToString();
            // This query is required because the earlier query returns results for only 1 page.
            r.iTotalRecords = core.BusinessUnits.Where(m => (m.DomainId == DomainId && m.BusinessUnitName.Contains(strSearch) && m.IsDroppedYN == "N")).Count();
            r.iTotalDisplayRecords = r.iTotalRecords;
            foreach (BusinessUnit bu in list)
            {
                List<string> r1 = new List<string>();
                string editurl = String.Format("<a href=\"/{0}/{1}/{2}\" id=\"editlink\" title=\"{1}\" >Edit</a>", "BusinessUnit", "Edit", bu.BusinessUnitId.ToString());
                string detailsurl = String.Format("<a href=\"/{0}/{1}/{2}\" id=\"detailslink\" title=\"{1}\" >Details</a>", "BusinessUnit", "Details", bu.BusinessUnitId.ToString());
                string deleteurl = String.Format("<a href=\"/{0}/{1}/{2}\" id=\"deletelink\" title=\"{1}\" >Delete</a>", "BusinessUnit", "Delete", bu.BusinessUnitId.ToString());
                string userurl = String.Format("<a href=\"/{0}/{1}/{2}\" >Users</a>", "User", "Index", bu.BusinessUnitId.ToString());
                r1.Add(editurl + detailsurl + deleteurl + userurl);
                r1.Add(bu.BusinessUnitName);
                r1.Add(String.Format("{0:d}<br />{0:t}", bu.ModifiedDT));
                r1.Add(bu.ModifiedByName);
                r1.Add(String.Format("{0:d}<br />{0:t}", bu.CreateDT));
                r1.Add(bu.CreatedByName);
                r.aaData.Add(r1);
            }
            return Json(r);
        }

        //
        // GET: /BusinessUnit/Details/5

        public ActionResult Details(Guid id)
        {
            CoreEntities core = new CoreEntities();
            BusinessUnit bu = core.BusinessUnits.First(b => b.BusinessUnitId == id);
            BUHelper.PopulatePlugins(core, ref bu, true);
            return View(bu);
        }

        //
        // GET: /BusinessUnit/Create

        [Permission("Can Create/Delete Domain, Can Modify Domain")]
        public ActionResult Create()
        {
            BusinessUnit bu = new BusinessUnit();
            bu.BusinessUnitId = Guid.NewGuid();
            bu.MainAddressId = Guid.NewGuid();
            bu.Address = new Address();
            bu.Address.AddressId = (Guid)bu.MainAddressId;
            bu.DomainId = (Guid)Session["DomainId"];
            CoreEntities core = new CoreEntities();
            BUHelper.PopulatePlugins(core, ref bu, false);
            return View(bu);
        } 

        //
        // POST: /BusinessUnit/Create

        [HttpPost]
        [Permission("Can Create/Delete Domain, Can Modify Domain")]
        public ActionResult Create(BusinessUnit bu)
        {
            try
            {
                // TODO: Add insert logic here
                if (ModelState.IsValid)
                {
                    bu.BusinessUnitId = Guid.NewGuid();
                    bu.DomainId = (Guid)Session["DomainId"];
                    bu.MainAddressId = bu.Address.AddressId;
                    bu.IsDroppedYN = "N";
                    bu.CreateDT = DateTime.Now;
                    bu.CreatedById = (Guid)Session["UserId"];
                    bu.CreatedByName = Session["UserFullName"].ToString();
                    bu.ModifiedDT = DateTime.Now;
                    bu.ModifiedById = (Guid)Session["UserId"];
                    bu.ModifiedByName = Session["UserFullName"].ToString();
                    CoreEntities core = new CoreEntities();
                    Guid MainAddressTag = core.Tags.First(m => (m.TagName == "Main Address" && m.BusinessUnitId == null)).TagId;
                    core.AddToBusinessUnits(bu);
                    //core.AddToAddresses(bu.Address);
                    BUAddress buaddress = new BUAddress();
                    buaddress.AddressId = (Guid)bu.MainAddressId;
                    buaddress.BusinessUnitId = bu.BusinessUnitId;
                    buaddress.TagId = MainAddressTag;
                    buaddress.IsPublicYN = bu.IsPublicAddress ? "Y" : "N";
                    core.AddToBUAddresses(buaddress);
                    BUHelper.UpdatePlugins(ref core, bu.BusinessUnitId, bu.PluginIds);
                    core.SaveChanges();
                    return RedirectToAction("Index");
                }
                else
                    return View(bu);
            }
            catch (Exception e)
            {
                ModelState.AddModelError("", Tools.ExceptionMessage(e));
                return View(bu);
            }
        }
        
        //
        // GET: /BusinessUnit/Edit/5
 
        public ActionResult Edit(Guid id)
        {
            CoreEntities core = new CoreEntities();
            Guid MainAddressTag = core.Tags.First(m => (m.TagName == "Main Address" && m.BusinessUnitId == null)).TagId;
            BusinessUnit bu = core.BusinessUnits.First(b => b.BusinessUnitId == id);
            bu.IsPublicAddress = (bu.BUAddresses.First(m => (m.TagId == MainAddressTag && m.AddressId == bu.MainAddressId)).IsPublicYN == "Y");
            BUHelper.PopulatePlugins(core, ref bu, false);
            return View(bu);
        }

        //
        // POST: /BusinessUnit/Edit/5

        [HttpPost]
        public ActionResult Edit(Guid id, FormCollection collection)
        {
            try
            {
                // TODO: Add update logic here
                if (ModelState.IsValid)
                {
                    CoreEntities core = new CoreEntities();
                    Guid MainAddressTag = core.Tags.First(m => (m.TagName == "Main Address" && m.BusinessUnitId == null)).TagId;
                    BusinessUnit bu = core.BusinessUnits.First(b => b.BusinessUnitId == id);
                    UpdateModel(bu, collection.ToValueProvider());
                    bu.ModifiedDT = DateTime.Now;
                    bu.ModifiedById = (Guid)Session["UserId"];
                    bu.ModifiedByName = Session["UserFullName"].ToString();
                    BUAddress buaddr = bu.BUAddresses.First(m => (m.TagId == MainAddressTag && m.AddressId == bu.MainAddressId));
                    buaddr.IsPublicYN = bu.IsPublicAddress ? "Y" : "N";
                    BUHelper.UpdatePlugins(ref core, id, collection.GetValues("PluginIds")[0].ToString());
                    core.SaveChanges();
                    return RedirectToAction("Index");
                }
                else
                    return View();
            }
            catch
            {
                return View();
            }
        }

        //
        // GET: /BusinessUnit/Delete/5

        [Permission("Can Create/Delete Domain, Can Modify Domain")]
        public ActionResult Delete(Guid id)
        {
            CoreEntities core = new CoreEntities();
            BusinessUnit bu = core.BusinessUnits.First(b => b.BusinessUnitId == id);
            BUHelper.PopulatePlugins(core, ref bu, true);
            return View(bu);
        }

        //
        // POST: /BusinessUnit/Delete/5

        [HttpPost]
        [Permission("Can Create/Delete Domain, Can Modify Domain")]
        public ActionResult Delete(Guid id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here
                CoreEntities core = new CoreEntities();
                BusinessUnit bu = core.BusinessUnits.First(b => b.BusinessUnitId == id);
                bu.IsDroppedYN = "Y";
                bu.ModifiedDT = DateTime.Now;
                bu.ModifiedById = (Guid)Session["UserId"];
                bu.ModifiedByName = Session["UserFullName"].ToString();
                core.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        [HttpPost]
        public JsonResult Plugins(string search, int maxitems)
        {
            CoreEntities core = new CoreEntities();
            List<Core.Models.Plugin> plugins = core.Plugins.Where(m => m.Name.Contains(search)).OrderBy(m => m.Name).Take(maxitems).ToList();
            List<NameId> data = new List<NameId>();
            foreach (Core.Models.Plugin plugin in plugins)
            {
                NameId item = new NameId();
                item.Name = plugin.Name;
                item.Id = plugin.PluginId.ToString();
                data.Add(item);
            }
            return Json(data);
        }
    }
}
